<template>
  <div class="pages">
    <div v-for="(page, pageIndex) in showData" :key="pageIndex" class="page">
      <div
        v-for="(blks, blksIndex) in page"
        :key="blksIndex"
        class="blks">
        <!-- 居中 -->
        <div v-if="blks.position === 'center'" class="center">
          <BlockContent v-for="(blk, i) in blks.data" :key="i" :block="blk" />
        </div>

        <!-- 左右分栏 -->
        <div v-if="blks.position === 'cols'" class="cols">
          <div v-for="(col, colIdx) in blks.data" :key="colIdx" class="col">
            <BlockContent v-for="(blk, i) in col?.data || []" :key="i" :block="blk" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
/* eslint-disable vue/require-name-property */
// import layout from '/public/55.json'
import katex from 'katex'
import 'katex/dist/katex.min.css'

export default {
  name: 'PdfViewer',
  props:{
    layout:{
      type:Object,
      default(){
        return {}
      }
    }
  },
  components: {
    BlockContent: {
      functional: true,
      props: { block: { type: Object, required: true } },
      render (h, { props }) {
        const { block } = props

        /* ---------- 渲染 span ---------- */
        const renderSpan = (span) => {
          const raw = span.content || ''
          if (span.type === 'inline_equation' || span.type === 'interline_equation') {
            try {
              let cleaned = raw
              if (span.type === 'inline_equation') {
                cleaned = raw.replace(/\\tag\{[^}]*\}/g, '')
              }
              return katex.renderToString(cleaned, {
                throwOnError: true,
                displayMode: span.type === 'interline_equation'
              })
            } catch (e) {
              console.warn('KaTeX 渲染失败:', raw, e)
              return `<code style="color:red;background:#fff3f3;padding:2px 4px;border-radius:3px;">${raw}</code>`
            }
          }
          return raw
        }

        /* ---------- 渲染文本块 ---------- */
        const renderText = () =>
          h(
            'div',
            { class: ['blk', block.type === 'title' ? 'title' : ''] },
            block.lines.map(line =>
              h('div', {
                class: 'line',
                domProps: {
                  innerHTML: line.spans.map(renderSpan).join('')
                }
              })
            )
          )

        /* ---------- 渲染图片 ---------- */
        const renderImage = () => {
          const imgBody = block.blocks.find(b => b.type === 'image_body')
          const imgSrc = imgBody?.lines?.[0]?.spans?.[0]?.image_path
          const captionLines = block.blocks
            ?.filter(b => b.type === 'image_caption')
            .flatMap(b => b.lines || [])

          // 渲染 caption 里的公式
          const captionHTML = captionLines
            .map(line => line.spans.map(renderSpan).join(''))
            .join('<br>')

          return h('div', { class: 'blk' }, [
            h('img', {
              attrs: {
                src: imgSrc,
                style: 'max-width:100%;height:auto;display:block;margin:0 auto;'
              }
            }),
            captionHTML
              ? h('div', {
                class: 'caption',
                domProps: { innerHTML: captionHTML }
              })
              : null
          ])
        }

        /* ---------- 渲染表格 ---------- */
        const renderTable = () => {
          const tableBody = block.blocks.find(b => b.type === 'table_body')
          const captionLines = block.blocks
            ?.filter(b => b.type === 'table_caption')
            .flatMap(b => b.lines || [])

          // 渲染 caption 里的公式
          const captionHTML = captionLines
            .map(line => line.spans.map(renderSpan).join(''))
            .join('<br>')

          if (tableBody?.lines?.[0]?.spans?.[0]?.html) {
            return h('div', { class: 'table-wrapper blk' }, [
              h('div', {
                domProps: { innerHTML: tableBody.lines[0].spans[0].html },
                style: 'overflow-x:auto;'
              }),
              captionHTML
                ? h('div', {
                  class: 'caption',
                  domProps: { innerHTML: captionHTML }
                })
                : null
            ])
          }

          if (tableBody?.lines?.[0]?.spans?.[0]?.image_path) {
            return h('div', { class: 'blk' }, [
              h('img', {
                attrs: {
                  src: tableBody.lines[0].spans[0].image_path,
                  style: 'max-width:100%;'
                }
              }),
              captionHTML
                ? h('div', {
                  class: 'caption',
                  domProps: { innerHTML: captionHTML }
                })
                : null
            ])
          }

          return null
        }

        /* ---------- 路由分发 ---------- */
        if (block.type === 'image') return renderImage()
        if (block.type === 'table') return renderTable()
        return renderText()
      }
    }
  },
  data () {
    return { showData: [] }
  },
  mounted () {
    this.getData()
  },
  methods: {
    getData () {
      const arr = []
      this.layout.pdf_info.forEach(page => {
        const pageArr = []
        const { para_blocks, page_size } = page
        const obj = { left: [], right: [], center: [] }

        para_blocks.forEach((blk, idx) => {
          const pos = this.getPosititon(blk, page_size)
          if (idx === 0) {
            obj[pos] = [blk]
          } else {
            const lastPos = this.getPosititon(para_blocks[idx - 1], page_size)
            if (pos === lastPos) {
              obj[pos].push(blk)
            } else {
              pageArr.push({ position: lastPos, data: [...obj[lastPos]] })
              obj[pos] = [blk]
            }
            if (idx === para_blocks.length - 1) {
              pageArr.push({ position: pos, data: [...obj[pos]] })
            }
          }
        })

        const final = []
        const cols = { position: 'cols', data: [{}, {}] }
        pageArr.forEach((p, i) => {
          const pos = p.position
          if (i === 0) {
            if (pos === 'center') final.push(p)
            else if (pos === 'left') cols.data[0] = p
          } else {
            const last = pageArr[i - 1].position
            if (last === 'left' && pos === 'right') {
              cols.data[1] = p
              final.push(JSON.parse(JSON.stringify(cols)))
            }
            if (pos === 'center') final.push(p)
            if (pos === 'left') cols.data[0] = p
          }
        })
        arr.push(final)
      })

      this.showData = arr
    },
    getPosititon (blk, [w]) {
      const [x, , x2] = blk.bbox
      if (x < w / 2 && x2 < w / 2) return 'left'
      if (x > w / 2) return 'right'
      return 'center'
    }
  }
}
</script>
<style lang="less">
/* 让公式块自动换行 */
.katex-display {
  font-size: 12px;
}

img {
  max-width: 100%;
  margin: 0 auto;
}

table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid #ccc;

  tr {
    border-bottom: 1px solid #ccc;

    td {
      border-right: 1px solid #ccc;
      padding: 0 10px;
    }
  }
}
</style>
<style lang="less" scoped>
.pages {
  width: 1000px;
  line-height: 1.6;
  margin: 0 auto;

  // font-size: 14px;
  .page {
    background: #f9f9f9;
    margin-bottom: 20px;
    padding: 100px 80px;
    border-radius: 8px;

    .blks {
      .center {
        margin-bottom: 20px;
      }

      .cols {
        display: flex;
        gap: 20px;

        .col {
          flex: 1;
        }
      }

      .blk {
        margin-bottom: 12px;
        // text-indent: 2em;
      }

      .title {
        font-weight: bold;
        font-size: 18px;
      }

      .caption {
        font-size: 12px;
        color: #555;
        text-align: center;
        margin-top: 4px;
      }

      .table-wrapper {
        overflow-x: auto;
      }
    }
  }
}
</style>